package com.huawei.fakedouyin.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.SeekBar;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;

import com.huawei.fakedouyin.R;
import com.huawei.fakedouyin.danmu.TextBean;
import com.huawei.fakedouyin.data.DmItem;
import com.huawei.fakedouyin.data.VideoInfo;
import com.huawei.fakedouyin.databinding.VideoLayoutBinding;
import com.huawei.fakedouyin.dialog.DanmuSwitchDialog;
import com.huawei.fakedouyin.manager.PlayManager;
import com.huawei.fakedouyin.service.SocketService;
import com.huawei.fakedouyin.util.ActivityUtil;
import com.huawei.fakedouyin.util.GsonUtil;
import com.huawei.fakedouyin.util.LiveDataSet;
import com.huawei.fakedouyin.util.LogUtil;
import com.huawei.fakedouyin.util.LogUtilKt;
import com.huawei.fakedouyin.util.MainExecutor;
import com.huawei.fakedouyin.util.SPUtil;
import com.huawei.fakedouyin.util.ScreenUtils;
import com.huawei.fakedouyin.util.ThreadPool;
import com.huawei.fakedouyin.util.TimeUtil;
import com.huawei.fakedouyin.video.TourVideoPlayer;
import com.huawei.faketaobao.constant.IConstant;
import com.huawei.faketaobao.constant.SPConstant;
import com.huawei.faketaobao.http.FakeRepository;
import com.huawei.faketaobao.http.ListResult;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlin.coroutines.EmptyCoroutineContext;

/**
 * 视频播放+弹幕界面
 */
public class MyVideoView extends ConstraintLayout {
    private static final int UPDATE_PROGRESS = 1;
    private static final int ADD_DANMU = 3;
    private static final int PLAY_VIDEO = 2;

    private VideoLayoutBinding binding;
    //视频播放时长
    public int mDuration;
    private Context mContext;
    private int pausePosition;
    private static boolean refresh = true;
    //正在播放的视频信息
    private VideoInfo mVideoInfo = null;
    //相应视频的弹幕原始列表
    public List<DmItem> dmItemList = new ArrayList<>();
    //弹幕的临时列表 是原始列表的复刻，进行删除等操作时不会影响原始数据
    public List<DmItem> tempDmList = new ArrayList<>();

    private String TAG = "MyVideoView";

    private OnProgressChangedListener mOnProgressChangedListener = null;

    private SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            binding.alreadyPlayText.setText(TimeUtil.formatTimeWhichExist(progress));
            if (mOnProgressChangedListener != null) {
                mOnProgressChangedListener.onProgressChanged(progress);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // 暂停刷新
            refresh = false;
            MyHandler.sendEmptyMessage(UPDATE_PROGRESS);
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int progress = seekBar.getProgress();
            if (binding.tourVideo != null) {
                MyHandler.removeMessages(UPDATE_PROGRESS);
                refresh = true;
                if (progress + 1000 < mDuration) {
                    // 设置当前播放的位置
                    binding.tourVideo.seekTo(progress);
                    MyHandler.sendEmptyMessage(UPDATE_PROGRESS);
                } else {
                    binding.tourVideo.pause();
                    start();
                }

            }
        }

    };


    public MyVideoView(Context context) {
        this(context, null);
    }

    public MyVideoView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        binding = VideoLayoutBinding.inflate(LayoutInflater.from(context), this, true);
        //进度条禁止拖动
        binding.seekBarProgress.setEnabled(false);
        //初始化各种监听
        initObserve();
        initView();
        initClick();
        refreshDanmuIcon();

    }

    private void initView() {
        //发送弹幕的入口
        binding.danmuImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //显示发送弹幕view
                LiveDataSet.danmuSendView.postValue(true);
            }
        });
    }

    /**
     * 开始获取弹幕
     */
    private void startBarrage() {
        //网络请求 获取该视频弹幕
        new FakeRepository().getBarrageList(mVideoInfo.getVideoId(), new Continuation<ListResult<DmItem>>() {
            @NonNull
            @Override
            public CoroutineContext getContext() {
                return EmptyCoroutineContext.INSTANCE;
            }

            @Override
            public void resumeWith(@NonNull Object o) {
                ListResult listResult = (ListResult) o;
                if (listResult.getCode() == IConstant.CodeSuccess) {
                    LogUtil.Companion.getInstance().logDebug("succcess");
                    dmItemList.clear();
                    //弹幕存储至原始列表
                    dmItemList.addAll(listResult.getData());
                    //刷新数据
                    refreshData();
                    LogUtil.Companion.getInstance().logDebug(tempDmList.toString());
                } else {
                    LogUtil.Companion.getInstance().logDebug("not code 200");
                }
            }
        });
    }

    /**
     * 重新装载临时数据
     */
    private void refreshData() {
        tempDmList.clear();
        //深拷贝原始列表 对临时弹幕列表进行删除等操作时 不会影响原始列表的数据
        tempDmList = GsonUtil.jsonToList(GsonUtil.toJsonString(dmItemList), DmItem.class);
        Log.d(TAG, "refreshdata dmitemlist:" + dmItemList.size());
        Log.d(TAG, "refreshdata tempDmList:" + tempDmList.size());
        //对弹幕进行排序
        refreshTempList(true);
    }

    /**
     * 对templist进行排序
     */
    public void refreshTempList(boolean reset) {
        //排序 按照发送时间排序
        Collections.sort(tempDmList, new Comparator<DmItem>() {
            @Override
            public int compare(DmItem o1, DmItem o2) {
                String sex1 = o1.getSendTime();
                String sex2 = o2.getSendTime();
                return sex2.compareTo(sex1);
            }
        });

        //重置数据状态
        if (reset) {
            for (int i = 0; i < tempDmList.size(); i++) {
                //全部更新状态为未添加状态
                tempDmList.get(i).setAdd(false);
            }
        }

    }

    /**
     * 状态监听
     */
    private void initObserve() {
        //弹幕总开关监听
        LiveDataSet.danmuSwitch.observeForever(MainExecutor.get(), new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                //弹幕开关监听
                setDanmuShow(aBoolean);
                //弹幕发送入口是否隐藏
                refreshDanmuIcon();
            }
        });


        //弹幕设置项变更  刷新
        LiveDataSet.changePlaySet.observeForever(new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                switch (integer) {
                    case 0://移动速度变更
                        binding.danmu2.refreshMoveSpeed();
                        break;

                    case 1://字体大小变更
                        binding.danmu2.refreshTextSizeChange();
                        break;

                    case 2://最大通道数变更 弹幕显示行数
                        binding.danmu2.refreshMaxLevel();
                        break;

                    case 3://透明度变更
                        binding.danmu2.refreshApl();
                        break;
                }
            }
        });
    }

    /**
     * 发弹幕
     *
     * @param dmItem
     * @param highLevel 等级 大于0就是高级弹幕
     */
    public boolean sendDanmu(DmItem dmItem, int highLevel) {
        //颜色未识别 默认白色
        int color = Color.WHITE;
        try {
            color = Color.parseColor(dmItem.getColor().startsWith("#") ? dmItem.getColor() : ("#" + dmItem.getColor()));
        } catch (Exception e) {
            color = Color.WHITE;
            LogUtil.Companion.getInstance().logDebug("颜色错误:" + dmItem.toString());
        }

        TextBean textBean = new TextBean();
        textBean.setColor(color);
        textBean.setText(dmItem.getMsg());
        textBean.setSize(dmItem.getFontSize() == 0);
        //是否高等级弹幕
        textBean.setHighLevel(highLevel);
        //添加弹幕至弹幕绘制列表
        return binding.danmu2.add(textBean);
    }

    /**
     * 弹幕发送入口 是否显示
     */
    private void refreshDanmuIcon() {
        if (SPUtil.Companion.getInstance().getBoolean(SPConstant.danmuSwitch, IConstant.danmuSwitch)) {
            binding.danmuImageView.setVisibility(View.VISIBLE);
        } else {
            binding.danmuImageView.setVisibility(View.GONE);
        }
    }

    /**
     * 默认弹幕 等级为0
     *
     * @param dmItem
     */
    private boolean sendDanmu(DmItem dmItem) {
        return sendDanmu(dmItem, dmItem.getLevel());
    }


    public void setProgressBarVisible(boolean visible) {
        binding.controllerLayout.setVisibility(visible ? VISIBLE : INVISIBLE);
    }

    /**
     * 弹幕开关
     *
     * @param show
     */
    private void setDanmuShow(boolean show) {
        SPUtil.Companion.getInstance().put(SPConstant.danmuSwitch, show);
        binding.danmu2.refreshSwitch();
    }

    /**
     * 发送handler开始播放视频
     *
     * @param video
     */
    public void playVideo(VideoInfo video) {
        MyHandler.removeMessages(PLAY_VIDEO);
        Message message = new Message();
        message.what = PLAY_VIDEO;
        message.obj = video;
        MyHandler.sendMessage(message);
    }

    /**
     * 初始化视频参数
     * @param video
     */
    private void initVideo(VideoInfo video) {
        if (video == null) {
            LogUtilKt.logDebug("init video but video is null");
            return;
        }
        LogUtil.Companion.getInstance().logDebug("initVideo:" + video.getVideoUrl());
        //视频时长
        mDuration = (int) video.getDuration();
        binding.alreadyPlayText.setText(TimeUtil.formatTimeWhichExist(mDuration));
        binding.seekBarProgress.setMax(mDuration);
        binding.totalPlayText.setText(TimeUtil.formatTimeWhichExist(mDuration));

        //宽高比
        int width = video.getWidth();
        int height = video.getHeight();

        float aspectRatio = (float) width / height;

        LayoutParams layoutParamsVideo = (LayoutParams) binding.tourVideo.getLayoutParams();
        LayoutParams layoutParamsThumb = (LayoutParams) binding.videoThumb.getLayoutParams();
        setLayoutParam(layoutParamsVideo, aspectRatio);
        setLayoutParam(layoutParamsThumb, aspectRatio);
        //设置视频大小比例
        binding.tourVideo.setLayoutParams(layoutParamsVideo);
        binding.videoThumb.setLayoutParams(layoutParamsThumb);
    }

    public void initClick() {
        //视频播放器的状态监听
        binding.tourVideo.setOnPlayChangeListener(new TourVideoPlayer.OnPlayStatusChange() {
            @Override
            public void onPlayChange(int status) {
                Log.d(TAG, "onPlayChange:" + status);
                switch (status) {
                    case TourVideoPlayer.STATE_PLAYING://开始|正在播放
                        //恢复弹幕绘制
                        binding.danmu2.onResume();
                        MyHandler.removeMessages(UPDATE_PROGRESS);
                        //恢复进度条刷新
                        MyHandler.sendEmptyMessage(UPDATE_PROGRESS);
                        //隐藏封面图片
                        binding.videoThumb.setVisibility(GONE);
                        //显示播放器
                        binding.tourVideo.setVisibility(VISIBLE);
                        //隐藏暂停按钮
                        binding.pauseIcon.setVisibility(GONE);
                        //是否显示播放进度
                        setProgressBarVisible(true);
                        changePlayIcon();
                        //  mp.setLooping(true);
                        //同步当前正在播放的视频信息
                        PlayManager.getInstance().usingInfo = mVideoInfo;

                        if (dmItemList.size() == 0) {
                            //通知服务器 正在观看该视频
                            SocketService.updateWatchStatus(true);
                            //通知服务器 正在观看该视频
                            LiveDataSet.watchMsg.postValue(mVideoInfo.getVideoId());
                            //未加载弹幕 开始加载
                            startBarrage();
                        }
                        break;

                    case TourVideoPlayer.STATE_COMPLETED://播放完成
                        //播放完成 重新播放
                        binding.alreadyPlayText.setText(TimeUtil.formatTimeWhichExist(mDuration));
                        //清空弹幕
                      //  binding.danmu2.finishAndClean();
                        //重置弹幕
                        refreshData();
                        binding.seekBarProgress.setProgress(0);
                        //重新播放
                        binding.tourVideo.restart();
                        break;

                    case TourVideoPlayer.STATE_PAUSED://视频暂停状态
                        //ui跟随播放器状态
                        binding.pauseIcon.setVisibility(VISIBLE);
                        //弹幕暂停
                        binding.danmu2.onPause();
                        MainExecutor.get().execute(() -> {
                            LogUtilKt.logDebug("video pause success");
                            //暂停更新进度条
                            MyHandler.removeMessages(UPDATE_PROGRESS);
                            pausePosition = binding.tourVideo.getCurrentPosition();
                            changePlayIcon();
                        });
                        break;

                }
            }
        });

        binding.controllerLayout.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        //暂停按钮
        binding.playBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

                if (binding.tourVideo.isPlaying()) {
                    pause();
                } else {
                    resume();
                }
            }
        });

        //单击为视频暂停和继续 全屏监听
        binding.clickRl.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                if (binding.tourVideo.isPlaying()) {
                    //暂停播放
                    pause();
                } else {
                    //恢复播放
                    resume();
                }
            }
        });

        //长按出现弹幕设置
        binding.clickRl.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                //显示弹幕设置弹框
                new DanmuSwitchDialog(ActivityUtil.Companion.getInstance().getCurrentActivity()).show();
                return true;
            }
        });

        binding.errorLayout.errorBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                start();
            }
        });

    }

    /**
     * 开始播放
     */
    public void start() {
        //开始播放
        binding.tourVideo.restart();
        binding.errorLayout.getRoot().setVisibility(GONE);
        changePlayIcon();
        refresh = true;
        binding.tourVideo.setVisibility(View.VISIBLE);
    }

    /**
     * 暂停
     */
    public void pause() {
        binding.tourVideo.pause();
    }

    /**
     * 播放器重新可见时调用
     */
    public void resume() {
        MainExecutor.get().execute(() -> {
            if (binding != null) {
                if (!binding.tourVideo.isPlaying()) {
                    LogUtilKt.logDebug("video resume");
                    binding.tourVideo.restart();
                }
            }
        });
    }

    /**
     * 停止播放
     */
    public void stop() {
        if (binding != null) {
            //清空弹幕
            binding.danmu2.onPause();
            dmItemList.clear();
            tempDmList.clear();
            binding.pauseIcon.setVisibility(GONE);
            binding.danmu2.finishAndClean();
            //停止进度条
            MyHandler.removeMessages(UPDATE_PROGRESS);
            //释放播放器
            binding.tourVideo.release();
            changePlayIcon();
            binding.seekBarProgress.setProgress(0);
            //封面图隐藏
            binding.videoThumb.setVisibility(GONE);

        }

    }

    private void setLayoutParam(LayoutParams layoutParams, float aspectRatio) {
        layoutParams.height = (int) (ScreenUtils.getScreenWidth(mContext) / aspectRatio);
    }

    private void changePlayIcon() {
        binding.playBtn.setBackground(ContextCompat.getDrawable(
                mContext,
                binding.tourVideo.isPlaying() ?
                        R.drawable.icon_video_pause :
                        R.drawable.icon_video_play));
    }

    private final Handler MyHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (binding.tourVideo == null) {
                return;
            }

            //更新进度
            if (msg.what == UPDATE_PROGRESS) {

                //当前视频播放进度
                int pausePosition = binding.tourVideo.getCurrentPosition();
                sendEmptyMessageDelayed(UPDATE_PROGRESS, 30);
                if (refresh) {
                    if (pausePosition > 0) {
                        //防止进度回退 部分视频会进度回退一下
                        if (pausePosition > binding.seekBarProgress.getProgress()) {
                            binding.seekBarProgress.setProgress(pausePosition);
                        }

                    }
                    binding.alreadyPlayText.setText(TimeUtil.formatTimeWhichExist(pausePosition + 1000));

                }

                //添加弹幕至绘制列表 绘制该弹幕
                synchronized (tempDmList) {
                    for (int i = 0; i < tempDmList.size(); i++) {
                        //差距在一定时间内 添加弹幕
                        //弹幕是否已被成功添加  弹幕的播放时间和视频的播放时间是否吻合
                        if (!tempDmList.get(i).isAdd() && Math.abs((tempDmList.get(i).getVideoTime() * 1000) - pausePosition) < 500) {
                            if (sendDanmu(tempDmList.get(i))) {
                                //添加成功  设置该弹幕状态
                                tempDmList.get(i).setAdd(true);
                            }
                        }
                    }
                }
                // LogUtil.Companion.getInstance().logDebug("msg time:" + pausePosition);

            }

            //准备播放
            if (msg.what == PLAY_VIDEO) {
                mVideoInfo = (VideoInfo) msg.obj;
                //binding.myVideoView.setVideoURI(Uri.parse(mVideoInfo.getVideoUrl()));
                //设置播放链接
                binding.tourVideo.setUp(mVideoInfo.getVideoUrl(), null);
                //显示封面图
                ThreadPool.getInstance().run(new Runnable() {
                    @Override
                    public void run() {
                        PlayManager.getInstance().createVideoThumbnail(mVideoInfo.getVideoUrl());
                    }
                });
                //显示封面图 缓存的bitmap
                binding.videoThumb.setImageBitmap(PlayManager.getInstance().getBitmap(mVideoInfo.getVideoUrl()));
                binding.videoThumb.setVisibility(VISIBLE);
                //初始化视频播放器
                initVideo(PlayManager.getInstance().getVideoInfo(mVideoInfo.getVideoUrl()));
                //开始播放
                start();
                //视频播放器添加至当前显示的视频列表item里
                LiveDataSet.showItem.postValue(true);
            }
        }
    };


    public VideoLayoutBinding getBinding() {
        return binding;
    }

    public void setOnProgressChangedListener(OnProgressChangedListener listener) {
        mOnProgressChangedListener = listener;
    }

    public interface OnProgressChangedListener {
        void onProgressChanged(int progress);
    }
}